package com.sky.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.*;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.*;
import com.sky.websocket.WebSocketServer;
import com.sun.deploy.ui.DialogTemplate;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.swing.*;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.record.DVALRecord;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


/**
 * @author iTaotao
 * @version 1.0
 * @Description 订单接口实现类
 * @createTime 2023年08月03日 14:15:00
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
    private final OrderMapper orderMapper;
    private final AddressBookMapper addressBookMapper;
    private final UserMapper userMapper;
    private final OrderDetailMapper orderDetailMapper;
    private final WebSocketServer webSocketServer;


    @Override
    public void reminder(Long id) {
        Orders orders = orderMapper.selectById(id);
        if (Objects.isNull(orders)) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        if (!Objects.equals(orders.getStatus(), Orders.TO_BE_CONFIRMED)) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        JSONObject map = new JSONObject();
        map.put("type", 2);
        map.put("orderId", id);
        map.put("content", orders.getNumber());
        webSocketServer.sendToAllClient(map.toJSONString());
    }

    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(BaseContext.getCurrentId());
        List<ShoppingCart> shoppingCartList = userMapper.selectList(shoppingCart);
        Orders orders = new Orders();
        long l = System.currentTimeMillis();
        orders.setNumber(String.valueOf(l));
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setUserId(BaseContext.getCurrentId());

        orders.setAddressBookId(ordersSubmitDTO.getAddressBookId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayMethod(1);
        orders.setPayStatus(0);
        BigDecimal amount = new BigDecimal(ordersSubmitDTO.getPackAmount() == null ? 0 : ordersSubmitDTO.getPackAmount());
        for (int i = 0; i < shoppingCartList.size(); i++) {
            amount = amount.add(shoppingCartList.get(i).getAmount());
        }
        orders.setAmount(amount);
        orders.setRemark(ordersSubmitDTO.getRemark());
        AddressBook addressBook = addressBookMapper.selectAddressById(ordersSubmitDTO.getAddressBookId());
        orders.setUserName(addressBook.getConsignee());
        orders.setPhone(addressBook.getPhone());
        String address = addressBook.getProvinceName() + addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail();
        orders.setAddress(address);
        orders.setConsignee(addressBook.getConsignee());
        orders.setEstimatedDeliveryTime(ordersSubmitDTO.getEstimatedDeliveryTime());
        orders.setDeliveryStatus(ordersSubmitDTO.getDeliveryStatus());
        // orders.setDeliveryTime();
        orders.setPackAmount(ordersSubmitDTO.getPackAmount());
        orders.setTablewareNumber(ordersSubmitDTO.getTablewareNumber());
        orders.setTablewareStatus(0);

        orderMapper.insert(orders);
        List<OrderDetail> orderDetails = shoppingCartList.stream().map(item -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(item, orderDetail);
            orderDetail.setOrderId(orders.getId());
            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailMapper.insert(orderDetails);

        userMapper.clean(BaseContext.getCurrentId());

        OrderSubmitVO orderSubmitVO = new OrderSubmitVO();
        orderSubmitVO.setId(orders.getId());
        orderSubmitVO.setOrderNumber(orders.getNumber());
        orderSubmitVO.setOrderAmount(orders.getAmount());
        orderSubmitVO.setOrderTime(orders.getOrderTime());


        return orderSubmitVO;


    }

    @Override
    public void repetitionAgain(Long id) {
        Orders orders = orderMapper.selectById(id);
        List<OrderDetail> orderDetailList = orderDetailMapper.selectOrderDetailByOrderId(orders.getId());
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(item -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(item, shoppingCart);
            shoppingCart.setUserId(BaseContext.getCurrentId());
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());
        userMapper.insertShopCartList(shoppingCartList);


    }

    @Override
    public PageResult page(Integer page, Integer pageSize, Integer status) {
//        PageHelper.startPage(page , pageSize);
//        Orders order = new Orders();
//        order.setUserId(BaseContext.getCurrentId());
//        order.setStatus(status);
//        Page<Orders> pageOrder = orderMapper.selectPage(order);
//        List<Orders> ordersList = pageOrder.getResult();
//
//
//        List<OrderVO> orderVOS = new ArrayList<>();
//        if(CollectionUtils.isNotEmpty(pageOrder)){
//            //把订单ids转换出来
//          List<Long> ordersIds = ordersList.stream().map(Orders::getId).collect(Collectors.toList());
//          //根据订单查询所有订单详情
//          List<OrderDetail> orderDetailList = orderDetailMapper.selectListByOrderIds(ordersIds);
//          orderVOS = ordersList.stream().
//                map(item->{
//              OrderVO orderVO = new OrderVO();
//              BeanUtils.copyProperties(item , orderVO);
//              List<OrderDetail> orderDetails = orderDetailList.stream()
//                      .filter(orderDetail -> Objects.equals(orderDetail.getOrderId() , item.getId()))
//                      .collect(Collectors.toList());
//              orderVO.setOrderDetailList((orderDetails));
//              return orderVO;
//          }).collect(Collectors.toList());
//        }
//
//
//        return new PageResult(pageOrder.getTotal(),orderVOS);


        PageHelper.startPage(page, pageSize);
        Orders orders = new Orders();
        orders.setUserId(BaseContext.getCurrentId());
        orders.setStatus(status);
        Page<Orders> ordersPage = orderMapper.selectPage(orders);
        List<Orders> ordersList = ordersPage.getResult();
        List<OrderVO> orderVOS = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ordersList)) {
            List<Long> orderIds = ordersList.stream().map(Orders::getId).collect(Collectors.toList());//所有的订单id
            List<OrderDetail> orderDetailList = orderDetailMapper.selectListByOrderIds(orderIds);//根据所有的订单id查询所有的订单详情表
            orderVOS = ordersList.stream().map(item -> {  //item ->所有的订单
                OrderVO orderVO = new OrderVO();
                BeanUtils.copyProperties(item, orderVO);

                List<OrderDetail> orderDetails = orderDetailList.stream().
                        filter(orderDetail -> Objects.equals(orderDetail.getOrderId(), item.getId())).collect(Collectors.toList());

                orderVO.setOrderDetailList(orderDetails);
                return orderVO;
            }).collect(Collectors.toList());
        }
        return new PageResult(ordersPage.getTotal(), orderVOS);

    }

    @Override
    public void cancelReminder(Long id) {
        Orders orders = new Orders();
        orders.setUserId(BaseContext.getCurrentId());
        orders.setId(id);
        orderMapper.updateStstus(orders);
    }

    @Override
    public void payNotification(String number) {
        orderMapper.payNotification(number, Orders.TO_BE_CONFIRMED);


        Orders orders = orderMapper.selectByNumber(number);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", 1);
        jsonObject.put("orderId", orders.getId());
        jsonObject.put("content", number);
        webSocketServer.sendToAllClient(jsonObject.toJSONString());

    }

    @Override
    public OrderVO selectOderById(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setUserId(BaseContext.getCurrentId());
        Orders orders1 = orderMapper.selectOrderById(orders);

        List<OrderDetail> orderDetails = orderDetailMapper.selectOrderDetailByOrder(id);

        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders1, orderVO);
        orderVO.setOrderDetailList(orderDetails);
        return orderVO;

    }

    @Override
    public TurnoverReportVO selectTurnoverStatistics(LocalDate begin, LocalDate end) {
        List<Map<String, Object>> mapList = orderMapper.selectTurnoverStatistics(begin, end);

        String orderTime = mapList.stream().map(map -> (String) map.get("format_order_time")).
                collect(Collectors.joining(","));

        String sumAmount = mapList.stream().map(map -> {
            BigDecimal sum_amount = (BigDecimal) map.get("sum_amount");
            return sum_amount.toString();
        }).collect(Collectors.joining(","));


        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setTurnoverList(sumAmount);
        turnoverReportVO.setDateList(orderTime);
        return turnoverReportVO;
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<Map<String, Object>> mapList = userMapper.selectUserStatistics(begin, end);
        List<Object> dateList = mapList.stream().map(item -> {
            String orderTime = (String) item.get("format_create_time");
            return orderTime;
        }).collect(Collectors.toList());

        String newUserList = mapList.stream()
                .map(item -> String.valueOf(item.get("count_user")))
                .collect(Collectors.joining(","));


        ArrayList<Integer> countList = new ArrayList<>();
        dateList.forEach(date -> {
            Integer count = userMapper.selectCountByCreateTime(date);
            countList.add(count);
        });

        String totalUserLsist = countList.stream().map(Object::toString).collect(Collectors.joining(","));
        UserReportVO userReportVO = new UserReportVO();
        userReportVO.setDateList(dateList.toString());
        userReportVO.setTotalUserList(totalUserLsist);
        userReportVO.setNewUserList(newUserList);
        return userReportVO;

    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<Map<String, Object>> orderrCountList = orderMapper.selectOrdersStatistics(begin, end);
        List<String> orderTimeList = orderrCountList.stream()
                .map(item -> (String) item.get("format_order_time"))
                .collect(Collectors.toList());

//        有效订单
        List<Integer> validOrderCountList = orderTimeList.stream().map(item -> {
                    Integer count = orderMapper.selectCountWithDate(item);
                    return count;

                })
                .collect(Collectors.toList());

        List<Long> ordersCountountList = orderrCountList.stream()
                .map(item -> (Long) item.get("orders_count"))
                .collect(Collectors.toList());
//        订单总数
        Long totalOrderList = ordersCountountList.stream().reduce(0L, Long::sum);
//        有效订单数
        Integer validCount = validOrderCountList.stream().reduce(0, Integer::sum);

//        订单完成率
        Double l = validCount.doubleValue() / totalOrderList;

//        处理订单总数
        //  String orderCountStr = ordersCountountList.stream().map(item -> Object::toString).collect(Collectors.joining(","));
        String orderCountStr = ordersCountountList.stream().map(Object::toString).collect(Collectors.joining(","));

//        处理有效订单数
        String validCountStr = validOrderCountList.stream().map(Object::toString).collect(Collectors.joining(","));

        OrderReportVO orderReportVO = new OrderReportVO();

        orderReportVO.setDateList(String.valueOf(orderTimeList));
        orderReportVO.setOrderCountList(orderCountStr);
        orderReportVO.setValidOrderCountList(validCountStr);
        orderReportVO.setTotalOrderCount(Math.toIntExact(totalOrderList));
        orderReportVO.setValidOrderCount(validCount);
        orderReportVO.setOrderCompletionRate(l);
        return orderReportVO;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List<Map<String, Object>> mapList = orderMapper.selectTop10(begin, end);
        String nameList = mapList.stream().map(item -> {
            String name = (String) item.get("name");
            return name;
        }).collect(Collectors.joining(","));

        String numberList = mapList.stream().map(item -> {
            Long dishCount = (Long) item.get("dish_count");
            return dishCount;
        }).map(item -> item.toString()).collect(Collectors.joining(","));

        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        salesTop10ReportVO.setNameList(nameList);
        salesTop10ReportVO.setNumberList(numberList);
        return salesTop10ReportVO;

    }


}

